﻿using lumo;
using lumo.display.animation2D;
using lumo.display.object2D;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace game.display.object2d
{

    /// <summary>
    /// 3-layered bar for general purpose
    /// </summary>
    public class SpriteBar
    {

        #region Points

        /// <summary>
        /// Start point
        /// </summary>
        protected float _Start;

        /// <summary>
        /// Start point (get / set)
        /// </summary>
        public float Start
        {
            get { return _Start; }
            set
            {
                float oldValue = _Start;
                _Start = MathHelper.Clamp(value, 0, _End - 1);

                if (_Start == oldValue)
                    return;

                _Current = MathHelper.Clamp(_Current, _Start, _End);
                Refresh();
            }
        }

        /// <summary>
        /// Current point
        /// </summary>
        protected float _Current;

        /// <summary>
        /// Current point (get / set)
        /// </summary>
        public float Current
        {
            get { return _Current; }
            set
            {
                float oldValue = _Current;
                _Current = MathHelper.Clamp(value, _Start, _End);

                if (_Current != oldValue)
                    Refresh();
            }
        }

        /// <summary>
        /// End point
        /// </summary>
        protected float _End;

        /// <summary>
        /// End point (get / set)
        /// </summary>
        public float End
        {
            get { return _End; }
            set
            {
                float oldValue = _End;
                _End = MathHelper.Clamp(value, 0, float.MaxValue);

                if (_End == oldValue)
                    return;

                _Start = MathHelper.Clamp(_Start, 0, _End - 1);
                _Current = MathHelper.Clamp(_Current, _Start, _End);

                Refresh();
            }
        }

        #endregion

        #region Sprite

        /// <summary>
        /// List of layers
        /// </summary>
        protected Sprite[] _Sprites;

        /// <summary>
        /// List of layers
        /// </summary>
        public Sprite[] Sprites { get { return _Sprites; } }

        /// <summary>
        /// Background layer
        /// </summary>
        public Sprite Background
        {
            get { return _Sprites[0]; }
            set { _Sprites[0] = value; }
        }

        /// <summary>
        /// Bar layer
        /// </summary>
        public Sprite Bar
        {
            get { return _Sprites[1]; }
            set { _Sprites[1] = value; }
        }

        /// <summary>
        /// Cover layer
        /// </summary>
        public Sprite Cover
        {
            get { return _Sprites[2]; }
            set { _Sprites[2] = value; }
        }

        #endregion

        /// <summary>
        /// Bar animation
        /// </summary>
        protected CropAnimation2D _Animation;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="background">Background layer</param>
        /// <param name="bar">Bar layer</param>
        /// <param name="cover">Cover layer</param>
        public SpriteBar(Texture2D background, Texture2D bar, Texture2D cover)
        {
            _Sprites = new Sprite[3] {
                new Sprite(background),
                new Sprite(bar),
                new Sprite(cover)
            };
        }

        /// <summary>
        /// Setups the bar according to the points
        /// </summary>
        /// <param name="start">Start point</param>
        /// <param name="current">Current point</param>
        /// <param name="end">End point</param>
        public void Setup(float start, float current, float end)
        {
            _End = MathHelper.Clamp(end, 0, float.MaxValue);
            _Start = MathHelper.Clamp(start, 0, _End - 1);
            _Current = MathHelper.Clamp(current, _Start, _End);
            int x = Convert.ToInt32(((Bar.Texture.Width * _Current) / (_End - _Start)));
            Bar.SourceRectangle = new Rectangle(0, 0, x, Bar.Texture.Height);

            _Animation = null;
        }

        /// <summary>
        /// Refreshes the animation
        /// </summary>
        protected void Refresh()
        {
            int x = (int)((Bar.Texture.Width * Current) / (_End - _Start));

            _Animation = new CropAnimation2D(
                new Rectangle(0, 0, x, Bar.Texture.Height),
                1000.0f,
                Smooth.Arrival,
                Loop.None,
                Bar
            );
        }

        /// <summary>
        /// Updates the bar animation
        /// </summary>
        /// <param name="component">Component</param>
        public void Update(LumoComponent component)
        {
            if (_Animation == null)
                return;
            _Animation.Update(component);
        }

        /// <summary>
        /// Draws the 3 layers
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _Sprites.Length; i++)
                _Sprites[i].Draw(spriteBatch);
        }

    }

}